﻿//
// Created by Freeman on 2022/1/23.
//

#include <cmath>
#include "../Headers/Util.h"
#include "../Headers/Exceptions.h"

using namespace std;

double Util::round(double x, int k) {
    if (k >= 10) return x; // 简单的越界检查
    return ::round(x * pow(10, k)) / pow(10, k);
}

bool Util::equal(double x, double y) {
    return (std::abs(x - y) <= eps);
}

bool Util::less(double x, double y) {
    return x < y - eps;
}

bool Util::more(double x, double y) {
    return x > y + eps;
}

bool Util::lessEqual(double x, double y) {
    return !more(x, y);
}

bool Util::moreEqual(double x, double y) {
    return !less(x, y);
}

std::vector<std::string> Util::strSplit(std::string str, char delimiter) {
    vector<string> v;

    // 去除首尾的分隔符
    string::size_type begin = str.find_first_not_of(delimiter), end = str.find_last_not_of(delimiter);
    if (begin == string::npos) return v; // 全为分隔符或空串
    str = str.substr(begin, end - begin + 1);

    begin = 0;
    end = str.find(delimiter, begin);
    while (end != string::npos) {
        v.push_back(str.substr(begin, end - begin));
        if (end == str.length() - 1) return v; // 最后一个字符是分隔符
        begin = end + 1;
        end = str.find(delimiter, begin);
    }
    v.push_back(str.substr(begin, str.length() - begin)); // 最后一个子串，或中间没有分隔符
    return v;
}

std::vector<int> Util::deci2AnyBase(int deci, int base) {
    vector<int> v;
    if (deci == 0) {
        v.push_back(0);
        return v;
    }
    else {
        int remainder = deci % base;
        if (deci / base > 0) v = deci2AnyBase(deci / base, base);
        v.push_back(remainder);
        return v;
    }
}

void Util::quickSort(std::vector<int> &v, int start, int end) {
    if (end <= start) throw IllegalArgumentException();
    if (end == start + 1) return; // 单元素

    int pivot = v[start];
    int i = start, j = end - 1;
    while (i < j) {
        while (i < j && v[j] >= pivot) j--;
        if (i < j) v[i] = v[j];
        while (i < j && v[i] <= pivot) i++;
        if (i < j) v[j] = v[i];
    }
    v[i] = pivot; // 循环终止时一定有i==j
    if (i > start + 1) quickSort(v, start, i); // 只有当序列长度至少为2时，继续向下递归
    if (end > i + 1) quickSort(v, i + 1, end);
}
